本文共 3862 字,大约阅读时间需要 12 分钟。
&pip install flask-login
安装完新的扩展以后不要忘记更新requirements.txt文件:
&pip freeze >requirements.txt
from flask_login import LoginManagerlogin_manager = LoginManager() #创建实例login_manager.session_protection = 'strong' #该参数有三个选项:None,'basic', 'strong', 保护用户会话不被窃取login_manager.login_view = 'auth.login' #记录登录视图def create_app(config_name): #... login_manager.init_app(app) #初始化 return app
flask_login要求实现下面四个用户方法;flask-login还要求程序实现一个回调函数, 根据用户id加载用户。
方法 | 说明 |
is_authenticated | 如果用户已经登录, 返回True |
is_active | 如果允许用户登录, 必须返回True;如果禁用账户,可以返回False |
is_anonymous | 对普通用户必须返回False |
get_id() | 必须返回用户的唯一标志符 |
我们可以自己在User类中实现这四个方法, 还有一更简便的做法是, 让User类继承UserMixin, 因为UserMixin已经实现了这四个方法:
from flask import UserMixinfrom . import db, login_managerclass User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), unique=True, index=True) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) password_hash = db.Column(db.String(128)) email = db.Column(db.String(64), unique=True, index=True) #为了便于登录, 我们增加了email字段, 对用户来说email地址比用户名更容易记住。#flask-login要求程序实现一个回调函数, 根据用户id加载用户:@login_manager.user_loaderdef load_user(user_id): return User.query.get(int(user_id))
该脚本定义登录表单:
from flask_wtf import FlaskFormfrom wtforms import StringField, PasswordField, BooleanField, SubmitFieldfrom wtforms.validators import Length, Email, DataRequiredclass LoginForm(FlaskForm): email = StringField('email', validators=[ Length(1, 64), Email() ]) password = PasswordField('password', validators=[ DataRequired() ]) remember_me = BooleanField('keep me log in') submit = SubmitField('log_in')
from . import authfrom .forms import LoginFormfrom ..models import Userfrom flask_login import login_user, login_required, logout_userfrom flask import redirect, request, url_for, flash, render_template@auth.route('/login', methods=['GET', 'POST'])def login(): form = LoginForm() if form.validate_on_submit(): #表单数据通过字段的验证函数 user = User.query.filter_by(email=form.email.data).first() #从数据库中查询有无该email的用户 if user and user.verify_password(form.password.data): #用户存在且密码正确 login_user(user, form.remember_me.data) #登录用户, 第二个参数是记住登录状态 #重定向, or前面的值是上个浏览页面(ps:登录页面)的url, 如果用户访问未授权的url就会重定向到登录页面, 否 #则返回主页。 return redirect(request.args.get('next') or url_for('main.index')) flash('Invalid email or password!') #如果用户不存在或者密码不正确刷新flash消息 return render_template('auth/login.html', form=form)@auth.route('/logout')@login_required #未授权用户访问该路由时会返回登录页面def logout(): logout_user() #登出用户 flash('You have been logged out') return redirect(url_for('main.index'))
current_user是flask-login提供的, 可以直接在视图函数和模板中使用, 如果当前用户已登录就显示Log Out, 否则显示Log In。
{% extends 'base.html' %}{% import 'bootstrap/wtf.html' as wtf %}{% block title %}Flasky{% endblock %}{% block page_content %}{ { wtf.quick_form(form) }}{% endblock %}Hello, {% if current_user.is_authenticated() %} { { current_user.username }} {% else %}Stranger{% endif %}!
{% if known%}happy to see you again{% else %}nice to meet you{% endif %}
{% extends 'base.html' %}{% import 'bootstrap/wtf.html' as wtf %}{% block title %}Flasky - Login{% endblock %}{% block page_content %}Login
{ { wtf.quick_form(form) }}{% endblock %}
&python manage.py shell
>u = User(email='1546879589@qq.com', username='john', password='cat')
>db.session.add(u)
>db.session.commit()